package com.contextor.magiccards.game.game.impl;

import com.contextor.magiccards.dao.utils.Pager;
import com.contextor.magiccards.dao.utils.ShardHelper;
import com.contextor.magiccards.game.BaseGameManager;
import com.contextor.magiccards.game.game.GameBattleManager;
import com.contextor.magiccards.model.battle.Battle;
import com.contextor.magiccards.model.battle.BattleStatus;
import com.contextor.magiccards.model.battle.Combat;
import com.contextor.magiccards.model.character.Personage;
import com.contextor.magiccards.model.errors.MagicCardsException;
import com.contextor.magiccards.model.errors.battle.BattleAlreadyExistsException;
import com.contextor.magiccards.model.errors.battle.CantJoinToOwnBattleException;
import com.contextor.magiccards.model.user.User;
import org.springframework.stereotype.Service;

import java.util.Collection;

/**
 * User: Sergey
 * Date: 20.03.2011 10:54:20
 */
@Service
public class GameBattleManagerImpl extends BaseGameManager implements GameBattleManager {

    public Battle create(String uid) throws MagicCardsException {
        final User user = userService.findByUid(ShardHelper.getShard(uid), uid);
        logger.info("create; userId={}", user.getId());
        Battle battle = battleService.findOwnerWithStatus(user, BattleStatus.READY_TO_PLAY);
        if (battle != null) {
            throw new BattleAlreadyExistsException("User has open battle; userId=" + user.getId());
        } else {
            logger.debug("create new Battle for userId={}", user.getId());
            final Personage personage = personageService.loadByUser(user);
            Battle newBattle = new Battle(user, personage, Battle.DEFAULT_MOVE_DURATION);
            battleService.save(ShardHelper.getShard(user.getUid()), newBattle);
            return newBattle;
        }

    }

    public Personage loadPersonage(String uid) throws MagicCardsException {
        final int shard = ShardHelper.getShard(uid);
        final User user = userService.loadByUid(shard, uid);
        logger.info("loadPersonage; userId={}, shard= {}", user.getId(), shard);
        return personageService.loadByUser(shard, user);
    }

    public Combat join(Personage personageTO, Battle battleTO) throws MagicCardsException {
        final int personageShard = ShardHelper.getShard(personageTO.getUid());
        final User personageOwner = userService.loadByUid(personageShard, personageTO.getUid());
        final int battleShard = ShardHelper.getShard(battleTO.getUid());
        final User battleOwner = userService.loadByUid(battleShard, battleTO.getUid());
        if (battleOwner.equals(personageOwner)) {
            throw new CantJoinToOwnBattleException("battleId=" + battleTO.getId() + " personageId=" + personageTO.getId());
        }
        Combat combat = new Combat();
        final Personage personageOfOwner = personageService.loadByUser(battleShard, battleOwner);
        combat.addCharacter(personageOfOwner);
        final Personage personage = personageService.loadByUser(personageShard, personageOwner);
        combat.addCharacter(personage);
        return combat;
    }

    public Collection<Battle> listReadyToPlay(String uid) throws MagicCardsException {
        final int shard = ShardHelper.getShard(uid);
        final User currentUser = userService.loadByUid(shard, uid);
        final Personage personage = personageService.loadByUser(currentUser);
        logger.info("listReadyToPlay; userId={}", currentUser.getId());
        return battleService.findWithStatus(shard, uid, BattleStatus.READY_TO_PLAY, new Pager(), personage);
    }
}
